package com.sc.nft.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sc.nft.dao.*;
import com.sc.nft.dto.EcologyHatchConfDao;
import com.sc.nft.entity.*;
import com.sc.nft.entity.vo.*;
import com.sc.nft.enums.*;
import com.sc.nft.exception.GlobalException;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.pool.UserPool;
import com.sc.nft.service.*;
import com.sc.nft.sup.ErrorCode;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * 服务接口实现
 *
 * @author rdg
 * @since 2022-05-30 10:53:23
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class IntegralExchangeServiceImpl implements IntegralExchangeService {
    private final UserReceiveIntegralDao userReceiveIntegralDao;
    private final DigitalCollectionProductInfoDao digitalCollectionProductInfoDao;
    private final UserCreatorInfoDao userCreatorInfoDao;
    private final StaticDataDao staticDataDao;
    private final UserAssetsDao userAssetsDao;
    private final BoxProductDao boxProductDao;
    private final BoxItemDao boxItemDao;
    private final CatenaInfoDao catenaInfoDao;
    private final UserAssetsService userAssetsService;
    private final UserExchangeRecordDao userExchangeRecordDao;
    private final UserCollectionService userCollectionService;
    private final UserConsensusService userConsensusService;
    private final ProductStockService productStockService;
    private final BoxItemService boxItemService;
    private final DigitalCollectionDao digitalCollectionDao;
    private final UserCollectionDao userCollectionDao;
    private final OrderDao orderDao;
    private final ProductStockDao productStockDao;

    @Override
    public FindIntegralVO findIntegral() {
        UserInfo userInfo = UserPool.getUser();
        FindIntegralVO findIntegralVO = new FindIntegralVO();
        UserAssets userAssets = userAssetsDao.getByUserIdAndCoinId(userInfo.getId(), CoinCategoryEnum.INTEGRAL.getCode());
        List<UserReceiveIntegralVo> list = userReceiveIntegralDao.findByUserId(userInfo.getId());
        for (UserReceiveIntegralVo userReceiveIntegralVo : list) {
            Long taskId = userReceiveIntegralVo.getTaskId();
            if (taskId.equals(IntegralTaskEnum.CONSUMPTION_INTEGRAL.getCode())) {
                LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(Order::getUserId, userInfo.getId()).eq(Order::getStatus, OrderStatusEnum.PAYMENT.getCode());
                wrapper.eq(Order::getIsDelete, Boolean.FALSE);
                int count = orderDao.count(wrapper);
                String information = userReceiveIntegralVo.getInformation();
                userReceiveIntegralVo.setInformation(information + count + "次");
            }
            if (taskId.equals(IntegralTaskEnum.INVITE_NEW_USER.getCode())) {
                String information = userReceiveIntegralVo.getInformation();
                userReceiveIntegralVo.setInformation(information + userInfo.getValidInviteNum() + "人");
            }
        }
        findIntegralVO.setId(userInfo.getId());
        findIntegralVO.setAssetsNum(userAssets.getTokenNum().toPlainString());
        findIntegralVO.setList(list);
        return findIntegralVO;
    }

    @Override
    public Page<IntegralExchangeProductVO> getIntegralExchangeList(Integer pageNo, Integer pageSize) {
        UserInfo user = UserPool.getUser();
        //不写sql这里有bug
        Page<IntegralExchangeProductVO> page = digitalCollectionProductInfoDao.getIntegralExchangeList(new Page(pageNo, pageSize));
        List<IntegralExchangeProductVO> records = page.getRecords();
        for (IntegralExchangeProductVO integralExchangeProductVO : records) {
            if (integralExchangeProductVO.getShowLevel() == 0) {
                integralExchangeProductVO.setShowLevelName("");
            }
            BigDecimal productNum = new BigDecimal(integralExchangeProductVO.getProductNum());
            Boolean flag = Boolean.FALSE;
            if (ObjectUtil.isNotEmpty(user)) {
                UserAssets userAssets = userAssetsDao.getByUserIdAndCoinId(user.getId(), CoinCategoryEnum.INTEGRAL.getCode());
                //用户积分余额大于商品积分价格则用户可以兑换
                if (userAssets.getTokenNum().compareTo(productNum) > -1) {
                    flag = Boolean.TRUE;
                }
            }
            integralExchangeProductVO.setFlag(flag);
        }
        return page;
    }

    @Override
    public IntegralProductDetailsVO getIntegralProductDetails(Long productId) {
        DigitalCollectionProductInfo digitalCollectionProductInfo = digitalCollectionProductInfoDao.getProductDetails(productId, 1, 2);
        if (ObjectUtil.isEmpty(digitalCollectionProductInfo)) {
            throw new GlobalRunTimeException(ErrorCode.PRODUCT_HAS_BEEN_DESCONTINUED);
        }
        UserInfo user = UserPool.getUser();
        UserAssets userAssets = userAssetsDao.getByUserIdAndCoinId(user.getId(), CoinCategoryEnum.INTEGRAL.getCode());
        Boolean flag = false;
        if (userAssets.getTokenNum().compareTo(digitalCollectionProductInfo.getIntegralNum()) > -1) {
            flag = Boolean.TRUE;
        }
        Long userCreatorId = digitalCollectionProductInfo.getUserCreatorId();
        UserCreatorInfo userCreatorInfo = userCreatorInfoDao.getById(userCreatorId);

        if (ObjectUtil.isEmpty(userCreatorInfo)) {
            throw new GlobalRunTimeException(ErrorCode.PRODUCT_HAS_BEEN_DESCONTINUED);
        }
        ProductStock productStock = productStockDao.getProductStock(productId, digitalCollectionProductInfo.getRelationId(), null);
        if (ObjectUtil.isEmpty(productStock)) {
            throw new GlobalRunTimeException(ErrorCode.PRODUCT_HAS_BEEN_DESCONTINUED);
        }
        Integer sumCount = productStock.getSumCount();
        Integer usableCount = productStock.getUsableCount();

        StaticData staticData = staticDataDao.getByType("purchase_notes");

        IntegralProductDetailsVO integralProductDetailsVO = BeanUtil.toBean(digitalCollectionProductInfo, IntegralProductDetailsVO.class);
        if (ObjectUtil.isEmpty(integralProductDetailsVO.getPrivilegePresentation())) {
            integralProductDetailsVO.setPrivilegePresentation("");
        }
        Integer count = userExchangeRecordDao.getByUserIdAndProductId(user.getId(), productId);
        Integer upperLimit = digitalCollectionProductInfo.getUpperLimit();
        if (upperLimit <= 0) {
            upperLimit = 20;
        }
        if (count >= upperLimit) {
            flag = Boolean.FALSE;
        }
        integralProductDetailsVO.setModelImg(digitalCollectionProductInfo.getModelImg());
        integralProductDetailsVO.setModelDistance(digitalCollectionProductInfo.getModelDistance());
        integralProductDetailsVO.setNickName(userCreatorInfo.getDaoName());
        integralProductDetailsVO.setCreatorPresentation(userCreatorInfo.getCreatorPresentation());
        integralProductDetailsVO.setCreatorAvatarImg(userCreatorInfo.getCreatorAvatarImg());
        integralProductDetailsVO.setProductId(productId);
        integralProductDetailsVO.setPurchaseNotes(staticData.getValue());
        integralProductDetailsVO.setFlag(flag);
        integralProductDetailsVO.setIsGive(flag);
        integralProductDetailsVO.setProductCount(sumCount);
        integralProductDetailsVO.setLaveNum(usableCount);
        integralProductDetailsVO.setCatenaName(digitalCollectionProductInfo.getCatenaName());
        integralProductDetailsVO.setSkipUrl(digitalCollectionProductInfo.getSkipUrl());

        List<UserCollection> list = userCollectionDao.findOneByProductIdAndUserId(digitalCollectionProductInfo, user);
        if (list.size() > 0) {
            integralProductDetailsVO.setIsHave(Boolean.TRUE);
        } else {
            integralProductDetailsVO.setIsHave(Boolean.FALSE);
        }
        return integralProductDetailsVO;
    }

    @Override
    public IntegralBoxDetailsVO getIntegralBlindBoxDetails(Long productId) {

        DigitalCollectionProductInfo digitalCollectionProductInfo = digitalCollectionProductInfoDao.getProductDetails(productId, 2, 2);

        if (ObjectUtil.isEmpty(digitalCollectionProductInfo)) {
            throw new GlobalRunTimeException(ErrorCode.PRODUCT_HAS_BEEN_DESCONTINUED);
        }

        UserInfo user = UserPool.getUser();
        UserAssets userAssets = userAssetsDao.getByUserIdAndCoinId(user.getId(), CoinCategoryEnum.INTEGRAL.getCode());
        Boolean flag = false;
        if (userAssets.getTokenNum().compareTo(digitalCollectionProductInfo.getIntegralNum()) > -1) {
            flag = Boolean.TRUE;
        }
        IntegralBoxDetailsVO integralBoxDetailsVO = BeanUtil.toBean(digitalCollectionProductInfo, IntegralBoxDetailsVO.class);
        integralBoxDetailsVO.setProductId(productId);
        StaticData staticData = staticDataDao.getByType("purchase_notes");
        integralBoxDetailsVO.setPurchaseNotes(staticData.getValue());
        Date beginTime = digitalCollectionProductInfo.getBeginTime();
        if (ObjectUtil.isEmpty(beginTime)) {
            integralBoxDetailsVO.setBeginTime("");
        } else {
            String forDate = DateUtil.format(beginTime, "MM-dd HH:mm:ss");
            integralBoxDetailsVO.setBeginTime(forDate);
        }
        Long userCreatorId = digitalCollectionProductInfo.getUserCreatorId();
        UserCreatorInfo userCreatorInfo = userCreatorInfoDao.getById(userCreatorId);
        if (ObjectUtil.isEmpty(userCreatorInfo)) {
            throw new GlobalRunTimeException(ErrorCode.PRODUCT_HAS_BEEN_DESCONTINUED);
        }
        integralBoxDetailsVO.setNickName(userCreatorInfo.getNickName());
        integralBoxDetailsVO.setCreatorAvatarImg(userCreatorInfo.getCreatorAvatarImg());

        ProductStock productStock = productStockDao.getProductStock(productId, digitalCollectionProductInfo.getRelationId(), null);
        if (ObjectUtil.isEmpty(productStock)) {
            throw new GlobalRunTimeException(ErrorCode.PRODUCT_HAS_BEEN_DESCONTINUED);
        }
        Integer sumCount = productStock.getSumCount();
        Integer usableCount = productStock.getUsableCount();
        Integer count = userExchangeRecordDao.getByUserIdAndProductId(user.getId(), productId);
        Integer upperLimit = digitalCollectionProductInfo.getUpperLimit();
        if (upperLimit <= 0) {
            upperLimit = 20;
        }
        if (count >= upperLimit) {
            flag = Boolean.FALSE;
        }

        List<BoxDigitalCollectionVO> boxDigitalCollection = boxItemDao.getDigitalCollections(digitalCollectionProductInfo.getRelationId());

        integralBoxDetailsVO.setList(boxDigitalCollection);

        CatenaInfo catenaInfo = catenaInfoDao.getById(digitalCollectionProductInfo.getCatenaId());
        if (ObjectUtil.isEmpty(catenaInfo)) {
            throw new GlobalRunTimeException(ErrorCode.PRODUCT_HAS_BEEN_DESCONTINUED);
        }
        integralBoxDetailsVO.setProductCount(sumCount);
        integralBoxDetailsVO.setLaveNum(usableCount);
        integralBoxDetailsVO.setCatenaPresentation(catenaInfo.getPresentation());
        integralBoxDetailsVO.setCatenaName(digitalCollectionProductInfo.getCatenaName());
        integralBoxDetailsVO.setFlag(flag);
        integralBoxDetailsVO.setIsGive(flag);
        return integralBoxDetailsVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void integralExchange(Long productId) throws GlobalException {
        Long userId = UserPool.getUser().getId();
        DigitalCollectionProductInfo digitalCollectionProductInfo = digitalCollectionProductInfoDao.getExchangeProduct(productId);
        if (digitalCollectionProductInfo.getProductType() != 1) {
            throw new GlobalRunTimeException(ErrorCode.NOT_BEGIN);
        }
        if (ObjectUtil.isEmpty(digitalCollectionProductInfo) || !digitalCollectionProductInfo.getStatus()) {
            throw new GlobalRunTimeException(ErrorCode.PRODUCT_HAS_BEEN_DESCONTINUED);
        }
        Integer count = userExchangeRecordDao.getByUserIdAndProductId(userId, productId);
        Integer upperLimit = digitalCollectionProductInfo.getUpperLimit();
        if (upperLimit <= 0) {
            upperLimit = 20;
        }
        if (count >= upperLimit) {
            throw new GlobalRunTimeException(ErrorCode.EXCHANGE_CAP);
        }
        ProductStock productStock = productStockDao.getProductStock(productId, digitalCollectionProductInfo.getRelationId(), null);
        if (productStock.getUsableCount() <= 0 || digitalCollectionProductInfo.getIsSoldOut()) {
            throw new GlobalRunTimeException(ErrorCode.COLLECTION_IS_SOLD_OUT);
        }
        UserAssets userAssets = userAssetsDao.getByUserIdAndCoinId(userId, CoinCategoryEnum.INTEGRAL.getCode());
        //用户积分数量小于商品积分价格
        if (userAssets.getTokenNum().compareTo(digitalCollectionProductInfo.getIntegralNum()) == -1) {
            throw new GlobalRunTimeException(ErrorCode.INTEGRAL_NOT_ENOUGH);
        }
        //减去用户积分
        Boolean aBoolean = userAssetsService.subIntegralByUserId(digitalCollectionProductInfo.getIntegralNum(), userId, CoinCategoryEnum.INTEGRAL, AssetChangeLogEnum.GOODS_EXCHANGE,digitalCollectionProductInfo.getId(),"兑换"+digitalCollectionProductInfo.getFirstTitle());
        if (aBoolean) {
            int num = 1;
            //减去商品库存
            productStockService.subIntegralStock(productId, digitalCollectionProductInfo.getRelationId(), null, 1, userId, CommodityType.INTEGRAL_PRODUCT);

            //插入用户拥有的藏品
            Long collectionId = null;
            boolean isOpen = false;
            Long boxId = null;
            String boxTitle = null;
            String boxImage = null;
            //如果兑换的是盲盒
            switch (digitalCollectionProductInfo.getTypeClassify()) {
                case COLLECTION:
                    isOpen = true;
                    collectionId = digitalCollectionProductInfo.getRelationId();
                    break;
                case BLIND_BOX:
                    BoxItem boxItem = boxItemService.openBox(productId, digitalCollectionProductInfo.getRelationId());
                    collectionId = boxItem.getCollectionId();
                    //减去盲盒库存
                    productStockService.subIntegralStock(productId, digitalCollectionProductInfo.getRelationId(), boxItem.getId(), 1, userId, CommodityType.INTEGRAL_PRODUCT);
                    BoxProduct boxProduct = boxProductDao.getById(digitalCollectionProductInfo.getRelationId());
                    boxId = boxProduct.getId();
                    boxTitle = boxProduct.getFirstTitle();
                    boxImage = digitalCollectionProductInfo.getCreationContent();
                    isOpen = false;
            }
            DigitalCollection digitalCollection = digitalCollectionDao.getById(collectionId);
            UserCollection userCollection = userCollectionService.addCollection(userId, null, digitalCollection.getId(), IdUtil.getSnowflakeNextIdStr(), digitalCollection.getCreationContent(), digitalCollection.getLevel(), digitalCollection.getFirstTitle(),
                    digitalCollection.getUserCreatorId(), ReceivedCollectionType.INTEGRAL, boxId, boxTitle, boxImage, isOpen, productId, 0L, 0L, digitalCollectionProductInfo.getProductNum(), 0,null,null,AddCollectionEnum.STAIR,null,null,false);
            if(digitalCollectionProductInfo.getTypeClassify()==ClassifyType.COLLECTION&&digitalCollection.getCollectionType()==DigitalMarketTypeEnum.ECOLOGY){
                    userConsensusService.adjustConsensusService(UserPool.getUser().getId(),digitalCollection.getId(),BigDecimal.ONE,UserConsensusTypeEnums.INTEGRAL_EXCHANGE,digitalCollection.getFirstTitle(),null);
            }
            //插入积分兑换记录
            UserExchangeRecord userExchangeRecord = new UserExchangeRecord();
            userExchangeRecord.setUserId(userId);
            userExchangeRecord.setProductInfoId(productId);
            userExchangeRecord.setTypeClassify(digitalCollectionProductInfo.getTypeClassify().getCode());
            userExchangeRecord.setIntegralNum(digitalCollectionProductInfo.getIntegralNum());
            userExchangeRecord.setIsSuccess(Boolean.TRUE);
            userExchangeRecord.setUserCollectionId(userCollection.getId());
            userExchangeRecord.setCollectionUuid(userCollection.getCollectionUuid());
            userExchangeRecord.insert();

            //插入藏品流转记录
            CollectionCirculatingRecord collectionCirculatingRecord = new CollectionCirculatingRecord();
            collectionCirculatingRecord.setCommodityType(CommodityType.INTEGRAL_PRODUCT);
            collectionCirculatingRecord.setTypeClassify(digitalCollectionProductInfo.getTypeClassify());
            collectionCirculatingRecord.setUserId(userId);
            collectionCirculatingRecord.setCollectionId(digitalCollection.getId());
            collectionCirculatingRecord.setReceivedCollectionType(ReceivedCollectionType.INTEGRAL);
            collectionCirculatingRecord.setUserReceiveIntegraId(userExchangeRecord.getId());
            collectionCirculatingRecord.insert();
        } else {
            throw new GlobalException(ErrorCode.LATER_TRY);
        }
    }

    @Override
    public List<UserExchangeRecordVo> getUserExchangeRecord() {
        Long userId = UserPool.getUser().getId();
        return userExchangeRecordDao.getUserExchangeRecord(userId);
    }


}
